const https = require('https');
const urlQuery = require("querystring");
const redis = require("../redis/redis-client");
const axios = require("axios");
const puppeteer = require("puppeteer");
// 引入 nodemailer 模块
const nodemailer = require("nodemailer");

let timer = null

// 创建一个 SMTP 传输对象
const transporter = nodemailer.createTransport({
    service: "qq", // 邮箱服务名
    auth: {
        user: "1@qq.com", // 邮箱账号
        pass: "" // 邮箱授权码
    }
});
let arrayList = [
    ["846/039/240043", "Y23GG187679T"],
    // ["261/970/212206存", "Y21G1187700MKC"],
    // ["261/970/212209存", "Y21G1187601RKC"],
    // ["261/970/230567P", "Y23G1187801WKC"],
    // ["932/653/220191存", "Y22G1184388A"],
    // ["932/653/211045存", "Y22G1184397"],
    // ["932/702/210649", "Y21G1187617R"],
    // ["261/970/211655", "Y21G1187628R"]
]
// let arrayList = [
//     "Y23G1184258SKC",
// ]
let arrayIndex = 0;
// 设置邮件选项
const mailOptions = {
    from: "1@qq.com", // 发件人邮箱
    to: "1@qq.com", // 收件人邮箱，可以是多个，用逗号分隔
    subject: "error", // 邮件主题
    text: "This is a test email from NodeMailer." // 邮件正文，纯文本格式
};


//使用 puppeteer.launch 启动 Chrome
(async function updateFn(currentI = 0, currentP = 1) {

    // 连接已打开的浏览器
    let wsKey = await axios.get('http://localhost:21222/json/version');
    const browser = await puppeteer.connect({
        browserWSEndpoint: wsKey.data.webSocketDebuggerUrl,
        defaultViewport: null,
        slowMo: 100,
        headless: true,
        timeout: 60000 * 5,
    })


    // 打开新的浏览器
    //   const browser = await puppeteer.launch(
    //     {
    //       headless: true,
    //       // headless: false,
    //       defaultViewport: {
    //         width: 1920,
    //         height: 1080
    //       },
    //       slowMo: 100,
    //       args: [
    //         '--no-sandbox',
    //         '--disable-features=site-per-process',
    //         '--start-maximized'
    //       ],
    //       timeout: 60000
    //     },
    //   );

    const page = await browser.newPage();
    await page.goto("http://10.139.3.16/sainty/");

    page.setDefaultNavigationTimeout(60000 * 5); // 1 hour

    const sendM = (reason) => {
        // 使用 transporter 对象的 sendMail 方法发送邮件
        // transporter.sendMail({ ...mailOptions, text: reason + "" }, (error, info) => {
        // });
    }


    // 当前在第几页
    let currentPage = currentP;

    // 出库工作台的数据列表
    let inputWorkbenchList = [];

    // 新增的采购合同信息item
    let addList = [];

    // 被修改过的商品信息的合同id
    let changeGoods = [];

    //当前执行的条数
    let currentItem = currentI;

    //每条占滚动条比率
    let ScrollRatio = 0;

    // 总分页数
    let totalpages = 0;

    // 总条数
    let totalItem = 0;

    // 每次移动条数
    const count = 15;


    // 监听error
    process.on('unhandledRejection', async (reason, p) => {
        console.error('Unhandled Rejection at: Promise:zk', 'reason:', reason);
        // changeGoods = [];
        // 开启新一轮轮循
        if (timer) {
            clearTimeout(timer)
        }

        timer = setTimeout(async () => {
            timer = null;
            let cp = currentPage - 1
            updateFn(cp * count, cp)
            await page.close();
            //  sendM(reason + "当前item" + cp * count + "当前页数" + cp)
        }, 5000);
    });

    const submitBtnEle = await page.$("input[id='LOGINSUBMIT']");
    if (submitBtnEle) {
        await submitBtnEle.click();
    }

    await page.waitForSelector(".menu-warp");
    const lineMenu = await page.$("a[title='仓储物流']");
    await lineMenu.click();

    const inputWorkbench = await page.$("a[title='成品入库工作台']");
    await inputWorkbench.click();

    const iframe = await page.waitForFrame((frame) => (frame.url().includes("InitValue.gtype")));

    if (iframe) {

        // 监听请求的响应的
        onPageList();

        await page.waitForTimeout(1000);


        // 输入采购合同号
        const purordcodElexEl = await iframe.$("input[name='purordcodex']");
        await purordcodElexEl.type(arrayList[arrayIndex][0], { delay: 20 });

        // 输入入库运编号
        const inputIdEl = await iframe.$("input[name='storagebatchno']");
        await inputIdEl.type(arrayList[arrayIndex][1]);

        arrayIndex++;
        // // 点击展开
        const developEl = await iframe.$("#UIA_purworkspaceQ__switchcss_ui-pane-collapsed");
        await developEl.click();

        // 取消勾选只查待入库>0
        const checkboxEl = await iframe.$("input[name='coropt#20']");
        await checkboxEl.click();

        // // 签约日期取消
        // const dateEl = await iframe.$("input[name='odate.[from]']");
        // await dateEl.click();
        // await page.keyboard.press('Backspace');

        // 选择年
        const dateEl = await iframe.$("#UIA_purworkspaceQ_odateform .ui-input-combobtn");
        await dateEl.click();
        const dayClass = await iframe.$$("#YMSELECT .ui-input-combobtn");
        await dayClass[0].click();

        await iframe.$$eval("#LIST .label span", node => node.map((el) => {
            console.log(el.innerText);
            if (el.innerText == "2018") {
                el.click()
            }
        }))
        // // 选择月
        // await dayClass[1].click();
        // await iframe.$$eval("#LIST .label span", node => node.map((el) => {
        //   console.log(el.innerText);
        //   if (el.innerText == "1") {
        //     el.click()
        //   }
        // }))
        // 选择日
        const selectedDay = await iframe.$("#DAYSELECT td.selectedday")
        await selectedDay.click()

        // 点击查询
        const searchEl = await iframe.$("#UIA_purworkspaceQ_btn_wrefreshtbls");
        await searchEl.click();

        await page.waitForTimeout(3000);

    }

    // 方法区--------------------------------------------------------------


    //获取完成入库工作台列表后执行
    async function forList() {
        await page.waitForTimeout(2000);

        //计算比率
        var scrollHeight = await iframe.$eval(".ui-gridtable .ui-grid-bar", el => el.scrollHeight);

        ScrollRatio = scrollHeight / totalItem;

        // 移除监听采购订单合同列表
        page.removeListener('response');

        onGoods();

        // redis.getString("enterCurrentPage").then(res => {
        //   if (res && res < totalpages) {
        //     currentPage = res;
        //     iframe.$eval(".ui-gridtable .ui-grid-bar", (el, { ScrollRatio, currentPage, count }) =>
        //       (el.scrollTop = ScrollRatio * currentPage * count),
        //       { ScrollRatio, currentPage, count }
        //     )
        //   }
        //   redis.getString("enterCurrentItem").then(res => {
        //     if (res && res < totalItem) {
        //       currentItem = res

        //       // redis.removeString("enterCurrentPage")
        //       // redis.removeString("enterCurrentItem")
        //     }
        //   })
        // })


        // -----------------------开始轮循点击采购合同---------------------------------
        await forClickId();
    }

    // 循环点击采购订单合同 结束后重新轮循获取入库工作台列表
    async function forClickId() {

        // 当前页面的合同id
        let div = await iframe.$$eval(".gtable tbody tr:not(.emptyrow) td:nth-child(2)", node => node.map((el) => el.innerText.trim()));
        console.log("div:", div);

        // 当前页面需要点击的元素
        let divId = await iframe.$$(".gtable tbody tr:not(.emptyrow) td:nth-child(2)");

        // 截取页面显示的count条记录
        // if (currentPage < totalpages) {
        //     divId = divId.slice(0, count)
        // }

        for (let i = 0; i < divId.length; i++) {
            console.log("当前索引：", i, "当前合同id", div[i]);
            let item = inputWorkbenchList.find(({ contractId }) => div[i] == contractId);
            if (item && item.goods.length == 0) {
                if (divId[i]) {
                    await divId[i].click({ clickCount: 2 })
                    await page.waitForTimeout(1000);
                }
                // 隐藏弹窗 影响点击事件
                const tiptext = await iframe.$(".x-tiptext.ui-layer-frame");
                if (tiptext) await iframe.$eval(".x-tiptext.ui-layer-frame", node => node.style.display = "none");

                const childIframe = await page.waitForFrame((frame) => (frame.url().includes("InitValue.purordicode")));

                const purordcode = await childIframe.$(" input[name='purordcode']")

                if (purordcode) {
                    const close = await page.$("#tabChangeUl li:last-child .icol-del3");

                    await page.waitForTimeout(1000);
                    await close.click()
                }
            }
            // 记录执行过的条数
            currentItem++;
            console.log("当前执行的条数", currentItem, "总条数：", totalItem, "当前滚动次数：", currentPage, "滚动总次数:", totalpages);
        }

        if (currentPage > totalpages) {
            // 使用 transporter 对象的 sendMail 方法发送邮件
            // transporter.sendMail({ ...mailOptions, text: "执行最后一页了" }, (error, info) => { });

            console.log("end---------inputWorkbenchList:");
            // 更新未同步的商品
            changeGoods.map((id) => {
                const index = inputWorkbenchList.findIndex(({ contractId }) => id == contractId);
                if (index > -1) {
                    sendUpdateGoodsToServer({ goods: inputWorkbenchList[index].goods })
                }
            })

            // redis.removeString("enterCurrentPage")
            // redis.removeString("enterCurrentItem")

            changeGoods = [];
            // 开启新一轮轮循
            page.close();
            setTimeout(() => {
                updateFn()
            }, 5000);
            return
        }

        if (currentPage <= totalpages) {
            // 执行完当前count条数 滚动翻页 继续执行
            // await iframe.waitForSelector(".ui-gridtable .ui-grid-bar");
            iframe.$eval(".ui-gridtable .ui-grid-bar", (el, { ScrollRatio, currentPage, count }) =>
                (el.scrollTop = ScrollRatio * currentPage * count),
                { ScrollRatio, currentPage, count }
            )

            currentPage++;
            await forClickId()
        }

    }

    // 监听采购合同点击
    function onGoods() {
        page.on("response", (response) => {
            if (response.status() == 200) {
                if (response.url().includes("27.15.20.G0.20.N9STJ.do.ui")) {

                    // url query 参数转json
                    const queryJson = urlQuery.parse(response.request().postData());

                    // 商品信息的接口
                    if (queryJson && queryJson.gcodeCuicode) {
                        response.text().then(res => {
                            // 解析字符串形的对象
                            const resData = eval("(" + res + ")");
                            // 存储的字段数组
                            const fields = resData.fields;

                            let goods = [];

                            resData.rows.map((item) => {
                                goods.push({
                                    "warehousingType": getValueByNameId("gstockmode", item[1], fields),//入库登记方式
                                    "transportId": item[2], //入库运编号
                                    "clientOrderId": item[3],//客户订单号
                                    "clientItemId": item[5], //客户货号
                                    "goodsType": getValueByNameId("gtype", item[6], fields),//货物类型
                                    "goodsName": item[7],//商品名称
                                    "goodsDesc": item[8],//商品描述
                                    "brand": item[12],//品牌
                                    "customsDeclaration": item[13],//单独报关
                                    "goodsCount": item[14],//签约数量
                                    "goodsUnits": getValueByNameId("qtcunit", item[15], fields),//签约单位
                                    // "purchasePrice": item[16],//采购单价
                                    "amount": item[17],//金额
                                    "deliveryDate": item[18],//交货日期
                                    "deliveryAddress": getValueByNameId("deliveryplace", item[19], fields),//交货地址
                                    "totalPackages": item[20], //包装件数 总件数
                                    "packagesUnit": getValueByNameId("qtxunit", item[21], fields), //包装单位
                                    "builtinNum": item[22], //内装数量
                                    "exteriorNum": item[23], //外装数量
                                    "roughWeight": item[24], //毛重
                                    "roughWeightTotal": item[25], //毛重合计
                                    "netWeight": item[26], //净重
                                    "netWeightTotal": item[27], //净重合计
                                    "packType": getValueByNameId("packtype", item[28], fields), //包装类型
                                    "matrixingRatio": item[51], //换算比例
                                    "total": item[52], //统计总数 总数量
                                    "units": getValueByNameId("qtcunit", item[53], fields), //统计单位
                                    "hsCode": item[54], //海关编码
                                    "shippingMark": item[55], //分唛头
                                    "remarks": item[56], //备注
                                    "contractId": item[62].trim()
                                });
                            });

                            // 如果有货品 把goods放入采购合同的goods里
                            if (goods.length) {
                                const item = inputWorkbenchList.find(({ contractId }) => contractId == goods[0].contractId);
                                if (item) {
                                    item.goods = goods;
                                }
                                // 要更新的商品信息
                                console.log("要更新的当前商品信息的合同列表changeGoods:", changeGoods);

                                // const index = changeGoods.findIndex((id) => goods[0].contractId == id);
                                // if (index > -1) {
                                // 发送更新的货品
                                sendUpdateGoodsToServer({ goods: goods });

                                console.log("2发送更新的goods:", "{ goods: goods }并删除goods", JSON.stringify(goods));
                                // changeGoods.splice(index, 1);
                                // }
                            }
                        })
                    }

                    // 商品详情的接口 获取合同id 和修改日期
                    if (queryJson && queryJson["__Json_._LoadWFInfo"]) {
                        response.text().then(res => {

                            // 解析字符串形的对象
                            const resData = eval("(" + res + ")");

                            // 发送待入库列表到后台
                            addList.map((item) => {

                                const listItemKey = item.contractId + item.clientItemId + item.goodsCount + item.warehousedNumber + item.notWarehousedNumber + item.notWarehousedPackages;

                                // resData.rows[0][0].trim() 合同ID
                                if (item.contractId == resData.rows[0][0].trim()) {
                                    console.log("发送入库列表", item.contractId)
                                    sendContractListToServer(item).then(() => {
                                        // 本地存储
                                        // key 合同id+客户货号+合同数量+已入库数量+未入库数量+未入库件数   value 1
                                        redis.setString(listItemKey, 1)
                                    }).catch(error => {
                                        console.log(error);
                                    })
                                }

                            });

                            // 服务端记录的修改时间
                            const changeTime = new Date(resData.rows[0][12]).getTime();

                            // key 合同id+time  value 修改时间
                            const key = resData.rows[0][0].trim() + "time"

                            // 获取本地存储的修改时间
                            redis.getString(key).then(res => {
                                // 本地没有代表首次或新增的数据 要保存到本地并更新
                                if (!res) {
                                    redis.setString(key, changeTime);
                                    // 
                                    console.log("changeGoods push的合同id:", resData.rows[0][0].trim());
                                    changeGoods.push(resData.rows[0][0].trim());
                                } else if (changeTime > res) {
                                    console.log("被修改的合同id:", resData.rows[0][0].trim());
                                    changeGoods.push(resData.rows[0][0].trim());
                                    // 更新本地的修改时间
                                    redis.setString(key, changeTime);
                                    console.log("修改时间:", changeTime, "当前保存的时间:", res, "是否修改过", changeTime > res);
                                }
                            });
                        })
                    }
                }
            }
        })
    }

    // 监听页面请求
    function onPageList() {
        page.on("response", (response) => {
            if (response.status() == 200) {
                if (response.url().includes("27.15.50.G0.30.N9STJ.do.ui")) {

                    // url query 参数转json
                    const queryJson = urlQuery.parse(response.request().postData());

                    // 当前组织代码 G118
                    if (queryJson && queryJson.storagebatchno && queryJson.storagebatchno.includes("18")) {
                        response.text().then(res => {
                            // 解析字符串形的对象
                            const resData = eval("(" + res + ")");
                            // 存储的字段数组
                            const fields = resData.fields;

                            // 总数据条数
                            totalItem = resData.rows.length;

                            // 计算需要拖动滚动条几次
                            totalpages = Math.floor(totalItem / count);

                            resData.rows.map((item) => {

                                let contractItem = {
                                    "contractId": item[1].trim(), //采购合同号
                                    "supplierName": getValueByNameId("ccode", item[5], fields), //供应商名称
                                    "goodsName": item[9],//商品名称
                                    "goodsCount": item[21],//合同数量
                                    "transportId": item[7], //入库运编号
                                    "clientItemId": item[8], //客户货号
                                    "deliveryDate": item[30], //交货日期
                                    "warehousedNumber": item[23],//已入库数量
                                    "notWarehousedNumber": item[24],//未入库数量
                                    "notWarehousedPackages": item[28],//未入库件数
                                    "exportContractId": item[29],//出口合同号
                                    "salesman": getValueByNameId("wcode", item[31], fields),//业务员
                                    "department": getValueByNameId("bcode", item[37], fields),//部门
                                    "operator": getValueByNameId("corpbcode", item[38], fields),//经营者
                                    "goods": [],
                                }

                                inputWorkbenchList.push(contractItem);

                                // key 合同id+客户货号+合同数量+已入库数量+未入库数量+未入库件数   value 1
                                const key = (item[1].trim() + item[8] + item[21] + item[23] + item[24] + item[28]);

                                redis.getString(key).then(res => {
                                    console.log(res);
                                    if (!res) {
                                        // 本地没有 需要更新
                                        addList.push(contractItem);
                                    }
                                });
                            })

                            console.log("需要更新的addList", addList);

                            // 循环获取列表
                            forList()
                        })
                    }
                }
            }
        })
    }

    /**
    * 
    * @param {*} name 字段标识
    * @param {*} Id 字段的id值
    * @param {*} array 所有的字段信息数组
    * @returns 匹配到的值
    */
    function getValueByNameId(name, Id, array) {
        let value = "";
        array.map((item) => {
            if (item.name == name) {
                value = item.valueMap[Id]
            }
        })
        return value
    }

    // 合同列表接口 发送数据
    function sendContractListToServer(data) {
        return new Promise((resole) => {
            const postData = JSON.stringify(data);
            // console.log(postData);
            const req = https.request({
                hostname: 'zhuyiyun.com',
                path: '/openapi/webhook/842298925882507267/842378384162422786',
                port: 443,
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'secretKey': '8b95cf4b511b49b2901272c4a1351b57'
                }
            }, (res) => {
                resole("ok")
                console.log("sendContractListToServer-发送合同列表-statusCode:", res.statusCode);
            });

            // 设置要发送的内容
            req.write(postData);
            // 如果出错就在控制台输出错误信息
            req.on('error', err => {
                console.log(err);
            });

            req.end();
        })
    }
    // 更新商品信息接口
    function sendUpdateGoodsToServer(data) {
        const postData = JSON.stringify(data);
        // console.log(postData);
        const req = https.request({
            hostname: 'zhuyiyun.com',
            path: '/openapi/webhook/842298925882507267/844579994607878146',
            port: 443,
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'secretKey': '8b95cf4b511b49b2901272c4a1351b57'
            }
        }, (res) => {
            console.log("sendUpdateGoodsToServer-发送货品-statusCode:", res.statusCode);
        });

        // 设置要发送的内容
        req.write(postData);
        // 如果出错就在控制台输出错误信息
        req.on('error', err => {
            console.log(err);
        });

        req.end();
    }

})();